package com.starbooks.tmail.annotation;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.text.SimpleDateFormat;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 *
 * @author huahuadavids
 * @date 2020/3/12
 */
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {DateValidator.DateValidatorInner.class})
public @interface DateValidator {

  /**
   * 必须的属性
   * 显示 校验信息
   * 利用 {} 获取 属性值，参考了官方的message编写方式
   *@see org.hibernate.validator 静态资源包里面 message 编写方式
   */
  String message() default "日期格式不匹配{dateFormat}";

  /**
   * 必须的属性
   * 用于分组校验
   */
  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

  /**
   * 非必须
   */
  String dateFormat() default "yyyy-MM-dd";

  /**
   * 必须实现 ConstraintValidator接口
   */
  class DateValidatorInner implements ConstraintValidator<DateValidator, String> {
    private String dateFormat;

    @Override
    public void initialize(DateValidator constraintAnnotation) {
      this.dateFormat = constraintAnnotation.dateFormat();
    }

    /**
     * 校验逻辑的实现
     * @param value 需要校验的值
     * @return 布尔值结果
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
      if (value == null) {
        return false;
      }
      if("".equals(value)){
        return false;
      }
      SimpleDateFormat sd=new SimpleDateFormat(dateFormat);//括号内为日期格式，y代表年份，M代表年份中的月份（为避免与小时中的分钟数m冲突，此处用M），d代表月份中的天数
      try {
        //此处指定日期/时间解析是否不严格，在true是不严格，false时为严格
        sd.setLenient(false);

        //从给定字符串的开始解析文本，以生成一个日期
        sd.parse(value);
      } catch (Exception e) {
        return false;
      }
      return true;
    }
  }
}
